Public.ObjectiveC is a Pike module that can be used to integrate ObjectiveC objects and Pike. ObjectiveC is most commonly associated with the http://developer.apple.com development environment used in MacOS X. Why? Originally, I wanted to be able to integrate with the Growl system to allow me to send messages and notifications from my Pike apps. Later, I decided that it might be cool to be able to write native Cocoa apps in Pike. This is the (in-progress) result of this. Some of the features currently available in this module:
Pike v7.7 release 30 running Hilfe v3.5 (Incremental Pike Frontend)
> import Public.ObjectiveC;
> load_bundle("Message.framework");
(1) Result: 0
> Cocoa.NSMailDelivery.deliverMessage_subject_to_("whee", "test message", "hww3@riverweb.com");
(2) Result: 1
import Public.ObjectiveC;
int i;
object pool;
void create()
{
Public.ObjectiveC.load_bundle("Growl.framework");
program g = get_dynamic_class("GrowlApplicationBridge");
g->setGrowlDelegate_(this);
}
int main()
{
call_out(notify, 6);
return -1;
}
object p;
mapping registrationDictionaryForGrowl(mixed ... args) {
mapping n = ([]);
n->ApplicationName = "PGrowl";
n->AllNotifications = ({"New Announcement"});
n->DefaultNotifications = ({"New Announcement"});
n->ApplicationIcon = Cocoa.NSWorkspace.sharedWorkspace()->iconForFileType_("jpg")->TIFFRepresentation();
return n;
}
void notify()
{
mapping n = ([]);
n->ApplicationName = "PGrowl";
n->NotificationName = "New Announcement";
n->NotificationPriority = Cocoa.NSNumber.numberWithInt_(2);
n->NotificationSticky = Cocoa.NSNumber.numberWithBool_(0);
n->NotificationTitle = "notification from PGrowl";
n->NotificationDescription = "whooo, it's " Calendar.now()->format_smtp() "!ngreetings from Public.ObjectiveC!";
n->NotificationIcon = Cocoa.NSWorkspace.sharedWorkspace()->iconForFileType_("jpg")->TIFFRepresentation();
n->NotificationAppIcon = Cocoa.NSWorkspace.sharedWorkspace()->iconForFileType_("jpg")->TIFFRepresentation();
get_dynamic_class("GrowlApplicationBridge")->notifyWithDictionary_(n);
// lather, rinse and repeat.
call_out(notify, 5);
}
import Public.ObjectiveC;
int i;
void create()
{
Public.ObjectiveC.low_load_bundle("/System/Library/Frameworks/Growl.framework");
NSClass("GrowlApplicationBridge")->setGrowlDelegate_(this);
}
int main()
{
call_out(notify, 6);
return -1;
}
object p;
object registrationDictionaryForGrowl(mixed ... args) {
object n = Cocoa.NSMutableDictionary->dictionaryWithCapacity(2);
n->setObject_forKey_("PGrowl", "ApplicationName");
n->setObject_forKey_(({"New Announcement"}), "AllNotifications");
n->setObject_forKey_(({"New Announcement"}), "DefaultNotifications");
n->setObject_forKey_(NSClass("NSWorkspace")->sharedWorkspace()->iconForFileType_("jpg")->TIFFRepresentation(),
"ApplicationIcon");
return n;
}
void notify()
{
object n = Cocoa.NSMutableDictionary->dictionaryWithCapacity(6);
n->setObject_forKey_("PGrowl", "ApplicationName");
n->setObject_forKey_("New Announcement", "NotificationName");
n->setObject_forKey_(Cocoa.NSNumber->new()->initWithInt_(2), "NotificationPriority");
n->setObject_forKey_(Cocoa.NSNumber->new()->initWithBool_(0), "NotificationSticky");
n->setObject_forKey_("notification from PGrowl", "NotificationTitle");
n->setObject_forKey_("whooo, it's " Calendar.now()->format_smtp() "!ngreetings from Public.ObjectiveC!", "NotificationDescription");
n->setObject_forKey_(NSClass("NSWorkspace")->sharedWorkspace()->iconForFileType_("jpg")->TIFFRepresentation(), "NotificationIcon");
n->setObject_forKey_(NSClass("NSWorkspace")->sharedWorkspace()->iconForFileType_("jpg")->TIFFRepresentation(), "NotificationAppIcon");
NSClass("GrowlApplicationBridge")->notifyWithDictionary_(n);
call_out(notify, 5);
}
import Public.ObjectiveC;
array fields = ({
Cocoa.ABAddressBook.kABLastNameProperty,
Cocoa.ABAddressBook.kABFirstNameProperty,
Cocoa.ABAddressBook.kABEmailProperty
});
int main()
{
object book = Cocoa.ABAddressBook.sharedAddressBook();
object p = book->people();
foreach(p;; object person)
{
array row = ({});
foreach(fields;; object f)
{
object fv = person->valueForKey_(f);
if(object_program(fv) == Cocoa.ABMultiValue)
row += ({(string)fv->valueAtIndex_(0) });
else row += ({(string)fv});
}
write((row*",") + "n");
}
}
#import <PikeInterpreter/OCPikeInterpreter.h>
#import <Foundation/NSString.h>
int main()
{
id i;
struct svalue * sv;
// required for console mode objective c applications
NSAutoreleasePool *innerPool = [[NSAutoreleasePool alloc] init];
// these 3 lines set up and start the interpreter.
i = [OCPikeInterpreter sharedInterpreter];
// we can optionally specify an alternate master, or use the one bundled in the framework.
[i setMaster: @"/usr/local/pike/7.7.30/lib/master.pike"];
[i startInterpreter];
// ok, now that we have things set up, let's use it.
// first, an example of calling pike c level apis directly.
f_version(0);
printf("%sn", Pike_sp[-1].u.string->str);
pop_stack();
// next, we'll demonstrate one of the convenience functions available
sv = [i evalString: @"1+2"];
printf("type: %d, value: %dn", sv->type, sv->u.integer);
free_svalue(sv);
// finally, we clean up.
[i stopInterpreter];
[innerPool release];
return 0;
}
import Public.ObjectiveC;
object NSApp;
class ConverterController
{
inherit Cocoa.NSObject;
object exchangeRate;
object dollarsToConvert;
object convertedAmount;
void convert_(object action)
{
float x;
x = exchangeRate->floatValue() * dollarsToConvert->floatValue();
convertedAmount->setFloatValue_(x);
}
}
int main(int argc, array argv)
{
NSApp = Cocoa.NSApplication.sharedApplication();
return AppKit()->NSApplicationMain(argc, argv);
}